home *** CD-ROM | disk | FTP | other *** search
- /*************************************************************************
- ** Apple Macintosh Developer Technical Support
- **
- ** A CalcControl Rgn Sample
- **
- ** by Matthew Xavier Mora,
- ** Apple Developer Technical Support
- ** mxmora@apple.com
- **
- ** File: Calc ControlRgn.c
- **
- ** Copyright © 1995-1996 Apple Computer, Inc.
- ** All rights reserved.
- **
- ** You may incorporate this sample code into your applications without
- ** restriction, though the sample code has been provided "AS IS" and the
- ** responsibility for its operation is 100% yours. However, what you are
- ** not permitted to do is to redistribute the source as "DSC Sample Code"
- ** after having made changes. If you're going to re-distribute the source,
- ** we require that you make it clear in the source that the code was
- ** descended from Apple Sample Code, but that you've made changes.
- **
- ** This sample shows how to call a CDEF to get the control's Region.
- **
- ** Version History
- **
- ** Date Initials Comments
- ** ----------------------------------------------------------------------
- ** 02-28-96 mxm added more comments and error checking
- ** 05-07-96 mxm got it ready for the cd
- **
- **************************************************************************/
-
- #include "SimpleApp.h"
-
- #define kPaintRegionOffset ( 200 )
- #define kNoOffset ( 0 )
- #define kNextButtonOffset ( 50 )
- #define kScrollBarFudge ( 15 )
- #define kMemorySystemErrMsg "\pMemory Manager error"
- #define kOurWindowTitle "\pCalculate a Control's Region Sample"
- #define kBadThingsMsg "\pBad things happened"
-
- // This is a quick macro for a function that is defined in the
- // next release of SimpleApp
-
- #define SAGetObjectRef(a) ((**a).buttonObject)
-
-
- pascal SInt16 DoButtonHit(ButtonItemRef me, SInt32 modifiers);
-
-
- //-------------------------------------------------------------------------
- // This function checks MemError and reports any errors returned
- //-------------------------------------------------------------------------
- static OSErr CheckMemoryError(void)
- //-------------------------------------------------------------------------
- {
- OSErr err;
-
- err = MemError();
- if (err) {
- ErrorMessage(kMemorySystemErrMsg,err,kSANonFatalError);
- }
- return err;
- }
-
- //-------------------------------------------------------------------------
- // A utility routine to lock a Handle and report any errors. It returns the
- // the state of the handle before it was locked so you can reset the handle
- // to its original state.
- //-------------------------------------------------------------------------
- static OSErr MyLockHandle(Handle theHandle,SInt8 * state)
- //-------------------------------------------------------------------------
- {
- OSErr err = noErr;
- SInt8 tempState;
-
- tempState = HGetState(theHandle); // remember the state
- err = CheckMemoryError(); // alert the user if error
- if (err == noErr) {
- HLock(theHandle);
- err = CheckMemoryError();
- }
- if (state) {
- *state = tempState;
- }
- return err;
- }
-
- //-------------------------------------------------------------------------
- // A utility routine to Set a Handle state and report any errors.
- //-------------------------------------------------------------------------
- static OSErr MySetHandleState(Handle theHandle,SInt8 state)
- //-------------------------------------------------------------------------
- {
- OSErr err = noErr;
-
- HSetState(theHandle,state); // remember the state
- err = CheckMemoryError(); // report any errors
- return err; // return error
- }
-
- //-------------------------------------------------------------------------
- // GetControlRgn takes a control handle and an existing Rgn
- // as parameters and will return in the control's rgn
- //-------------------------------------------------------------------------
- static OSErr GetControlRegion(ControlHandle ch,RgnHandle theRgn)
- //-------------------------------------------------------------------------
- {
- Handle cdefHandle; // Handle to the control Proc
- SInt16 errorState = noErr ; // preset error state
-
- if ( (ch != nil) && (theRgn != nil) ) { // make sure we have a control and Rgn
- cdefHandle = (**ch).contrlDefProc; // Get the control's Handle
- if (!*cdefHandle) { // lets load it in if its not
- LoadResource(cdefHandle);
- errorState = ResError(); // check for error
- }
- if ((*cdefHandle) != nil && errorState == noErr ) { // all is well
- SInt8 state ; // holding place for handle state
- errorState = MyLockHandle(cdefHandle,&state);
- if (errorState == noErr) {
- UInt32 result; // the result we don't care about
- ControlDefUPP myControlUPP; // Holding place for the CDEF ProcPtr or UPP
- //
- myControlUPP = (ControlDefUPP)(*cdefHandle);
- // What? Casting to a UPP? Are you crazy?
- // The reason you cast in instead of creating a UPP
- // is that it may already be a UPP (ie native CDEF)
- // and dual UPP's would really confuse Mixed Mode. If its not
- // a upp, CallControlDefProc does the right thing by passing a
- // a valid ProcInfo to CallUniversalProc which makes
- // mixed mode a happy camper in any case.
- result = CallControlDefProc(myControlUPP,
- GetControlVariant(ch),
- ch,
- calcCntlRgn,
- (SInt32)theRgn);
- errorState = MySetHandleState(cdefHandle,state); // reset the handle state
- }
- }
- } else { // ControlHandle or theRgn is nil
- errorState = nilHandleErr; // set the error
- }
- return (errorState); // be sure and return any errors
- }
-
- //-------------------------------------------------------------------------
- // Simple routine to paint the region we get from the Control
- //-------------------------------------------------------------------------
- static OSErr DisplayControlRgn(ControlHandle ch)
- //-------------------------------------------------------------------------
- {
- RgnHandle theRgn;
- SInt16 err = noErr;
-
- theRgn = NewRgn(); // Get a region to work with
- if (theRgn) {
- err = GetControlRegion(ch,theRgn); // Get the Button's Region
- if (err == noErr){
- OffsetRgn(theRgn,kPaintRegionOffset,kNoOffset);
- PaintRgn(theRgn);
- DisposeRgn(theRgn);
- } else {
- err = CheckMemoryError();
- }
- }
- return (err);
- }
-
-
- //-------------------------------------------------------------------------
- // This gets called when the Click Me button is clicked.
- // ------------------------------------------------------------------------
- // Note!
- // There is a problem with global optimization and call back functions.
- // If you want global optimization on for the rest of your code you
- // should turn it off for any call back functions unless MW has released
- // a fix. i.e #pragma optimization_level 1
- //-------------------------------------------------------------------------
- pascal short DoButtonHit(ButtonItemRecHandle me, long modifiers)
- //-------------------------------------------------------------------------
- {
- #pragma unused (modifiers)
-
- ControlRef cr = nil;
- OSErr err = noErr;
-
- cr = SAGetObjectRef(me);
- if (cr) {
- err = DisplayControlRgn(cr);
- if (err != noErr) {
- ErrorMessage(kBadThingsMsg,err,kSANonFatalError);
- }
- }
- return err;
- }
-
- //-------------------------------------------------------------------------
- // This gets called when the Clear button is clicked.
- //-------------------------------------------------------------------------
- static pascal SInt16 DoClear(ButtonItemRef me, SInt32 modifiers)
- //-------------------------------------------------------------------------
- {
- #pragma unused (modifiers)
- #pragma unused (me)
- Rect r;
-
- r = gSACurrentWindow->portRect; // Get the window's portRect
- r.left += kPaintRegionOffset; // offset so it doesn't erase
- r.right -= kScrollBarFudge; // our buttons and scroll bar
- r.bottom -= kScrollBarFudge; // areas
- InvalRect(&r);
- return noErr;
- }
-
- //-------------------------------------------------------------------------
- // This is the main function. Note how simple it is. It installs
- // two Buttons and then lets SimpleApp handle the rest.
- //
- //-------------------------------------------------------------------------
- void main(void)
- //-------------------------------------------------------------------------
- {
- Rect r;
- SInt32 buttonID;
- SInt16 gMyWindowID;
- SInt16 err;
-
- InitSimpleApp(1,kUseStandardMenu); // Simple App Sets up the Tool Box For us
- gMyWindowID = GetDocumentWindow (128); // Get our stored window
- // the global gSACurrentWindow is maintained
- // by SimpleApp and it contains the active
- // document window reference
- SetWTitle(gSACurrentWindow,kOurWindowTitle);// set the window title so we know what we are running
- SetRect(&r,10,30,100,50); // set the control bounds
- err = InstallPushButton (&buttonID, // Reference ID (we don't care)
- gSACurrentWindow, // Owner Window
- "\pClick Me", // Name
- &r, // Bounds
- kSANoCommandKey, // Command Key
- DoButtonHit , // Button Hit
- nil // Button Update Proc
- );
- OffsetRect(&r,kNoOffset,kNextButtonOffset);
- err = InstallPushButton (&buttonID, // Reference ID (we don't care)
- gSACurrentWindow, // Owner Window
- "\pClear", // Name
- &r, // Bounds
- kSANoCommandKey, // Command Key
- DoClear , // Button Hit Proc
- nil // Button Update Proc
- );
- Run(); // Let SimpleApp handle the rest
- }
-
-